package roborally.model;

/**
 * An interface for dealing with objects,
 * which have the capacity to store energy.
 * 
 * @version 1.0
 * @author  Pieter Robberechts	(1e Bach Informatica)
 * @author	Jeroen Sanders		(1e Bach Informatica)
 */
public interface IEnergyHolder {

	/**
	 * Return the amount of energy an energyHolder is holding. 
	 */
	public EnergyAmount getEnergy();
	
	/**
	 * Check whether an energyHolder can store a given
	 * amount of energy.
	 * 
	 * @param 	ws
	 * 			The amount of energy to check for whether or not it can be stored.
	 */
	public boolean canHaveAsEnergy(EnergyAmount ws);
	
	/**
	 * Recharge an energyHolder with the given amount of energy.
	 * 
	 * @param 	amount
	 * 			The amount of energy to recharge with.
	 * @pre		...
	 * 			| amount != null
	 * @pre		...
	 * 			| canHaveAsEnergy( getEnergy().add(amount) )
	 * @post	...
	 * 			| new.getEnergy().isIdenticalTo( getEnergy().add(amount) )
	 */
	public void recharge(EnergyAmount amount);
	
	/**
	 * Transfer a given amount of energy between two energyHolders
	 * 
	 * @param 	other
	 * 			The energyHolder to transfer energy to.
	 * @param 	amount
	 * 			The amount of energy to transfer.
	 * @pre		...
	 * 			| other != null
	 * @pre		...
	 * 			| amount != null
	 * @pre		...
	 * 			| ! other.isTerminated()
	 * @pre		...
	 * 			| other.canHaveAsEnergy( getEnergy().add(amount) )
	 * @pre		...
	 * 			| this.canHaveAsEnergy( getEnergy().subtract(amount) )
	 * @post	...
	 * 			| this.new.getEnergy().isIdenticalTo( this.getEnergy().subtract(amount) )
	 * @post	...
	 * 			| other.new.getEnergy().isIdenticalTo( other.getEnergy().add(amount) )
	 */
	public void transferEnergy(IEnergyHolder other, EnergyAmount amount);
	
	/**
	 * Check whether this energyHolder is terminated.
	 */
	public boolean isTerminated();
}
